/**
 * 
 */
package org.gigi.security.service.base;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.gigi.core.Page;
import org.gigi.security.domain.Authority;
import org.gigi.security.domain.Group;
import org.gigi.security.domain.GroupUser;
import org.gigi.security.domain.User;
import org.gigi.security.repository.GroupRepository;
import org.gigi.security.service.GroupService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 默认的角色服务层实现
 *
 * @author Eugene Wang 2011-9-1
 * @see
 */
@Service
@Transactional(readOnly = true)
public class DefaultGroupService implements GroupService {
	@Autowired
	private GroupRepository groupRepository;
	/* (non-Javadoc)
	 * @see org.gigi.security.service.RoleService#create(org.gigi.security.domain.Role)
	 */
	@Override
	@Transactional
	public void create(Group group) {
		groupRepository.create(group);
	}

	/* (non-Javadoc)
	 * @see org.gigi.security.service.RoleService#findByParentId(long)
	 */
	@Override
	public List<Group> findChildren(long parentId) {
		return groupRepository.findChildren(parentId);
	}

	/* (non-Javadoc)
	 * @see org.gigi.security.service.RoleService#delete(long)
	 */
	@Override
	@Transactional
	public void delete(long id) {
		Group group = groupRepository.findById(id);
		groupRepository.delete(group);
	}

	/* (non-Javadoc)
	 * @see org.gigi.security.service.RoleService#update(org.gigi.security.domain.Role)
	 */
	@Override
	@Transactional
	public void update(Group group) {
		Group dbRole = groupRepository.findById(group.getId());
		BeanUtils.copyProperties(group, dbRole, new String[] {"parent", "authorities"});
		groupRepository.update(dbRole);
	}

	/* (non-Javadoc)
	 * @see org.gigi.security.service.RoleService#get(long)
	 */
	@Override
	public Group findById(long id) {
		return groupRepository.findById(id);
	}

	/* (non-Javadoc)
	 * @see org.gigi.security.service.GroupService#getUserPage(org.gigi.core.Page)
	 */
	@Override
	public Page<User> getUserPage(Group group, Page<User> page) {
		return groupRepository.getUserPage(group, page);
	}

	/* (non-Javadoc)
	 * @see org.gigi.security.service.GroupService#addUsers(long, java.util.List)
	 */
	@Override
	@Transactional
	public void addUsers(Group group, List<User> users) {
		List<GroupUser> groupUsers = populateGroupUsers(group, users);
		groupRepository.addUsers(groupUsers);
	}

	/* (non-Javadoc)
	 * @see org.gigi.security.service.GroupService#removeUsers(long, java.util.List)
	 */
	@Override
	@Transactional
	public void removeUsers(Group group, List<User> users) {
		List<GroupUser> groupUsers = populateGroupUsers(group, users);
		groupRepository.removeUsers(groupUsers);
	}
	/**
	 * 根据用户组和用户列表，组装用户组用户列表。
	 * @param group
	 * @param users
	 * @return
	 */
	private List<GroupUser> populateGroupUsers(Group group, List<User> users) {
		List<GroupUser> groupUsers  = new ArrayList<GroupUser>();
		for (User user : users) {
			groupUsers.add(new GroupUser(group, user));
		}
		return groupUsers;
	}

	/* (non-Javadoc)
	 * @see org.gigi.security.service.GroupService#getNonUserPage(org.gigi.security.domain.Group, org.gigi.core.Page)
	 */
	@Override
	public Page<User> getNonUserPage(Group group, Page<User> page) {
		return groupRepository.getNonUserPage(group, page);
	}

	/* (non-Javadoc)
	 * @see org.gigi.security.service.GroupService#findGroupAuthorities(long)
	 */
	@Override
	public List<Authority> findGroupAuthorities(long groupId) {
		Group group = groupRepository.findById(groupId);
		Set<Authority> authorities = group.getAuthorities();
		return new ArrayList<Authority>(authorities);
	}

	/* (non-Javadoc)
	 * @see org.gigi.security.service.GroupService#addAuthorities(org.gigi.security.domain.Group, java.util.List)
	 */
	@Override
	@Transactional
	public void addAuthorities(Group group, List<Authority> authorities) {
		Group dbGroup = groupRepository.findById(group.getId());
		Set<Authority> dbAuthorities = dbGroup.getAuthorities();
		for (Authority authority : authorities) {
			dbAuthorities.add(authority);
		}
	}

	/* (non-Javadoc)
	 * @see org.gigi.security.service.GroupService#deleteAuthorities(org.gigi.security.domain.Group, java.util.List)
	 */
	@Override
	@Transactional
	public void deleteAuthorities(Group group, List<Authority> authorities) {
		Group dbGroup = groupRepository.findById(group.getId());
		Set<Authority> dbAuthorities = dbGroup.getAuthorities();
		for (Authority authority : authorities) {
			dbAuthorities.remove(authority);
		}
	}
}
